package com.beforedawn.judge;

import com.beforedawn.compare.Compare;
import com.beforedawn.compile.Compile;
import com.beforedawn.compile.CompileState;
import com.beforedawn.run.Run;
import com.beforedawn.util.DeleteFile;
import com.beforedawn.util.RunData;

import java.io.File;

/**
 * 判题类
 *
 * @author moyulingjiu
 * @date 2021年11月23日
 */
public class Judge {
    private Compile compile;
    private Run run;
    private Compare compare;

    public Judge(Compile compile, Run run, Compare compare) {
        this.compile = compile;
        this.run = run;
        this.compare = compare;
    }

    public Compile getCompile() {
        return compile;
    }

    public void setCompile(Compile compile) {
        this.compile = compile;
    }

    public Run getRun() {
        return run;
    }

    public void setRun(Run run) {
        this.run = run;
    }

    public Compare getCompare() {
        return compare;
    }

    public void setCompare(Compare compare) {
        this.compare = compare;
    }

    /**
     * 参数说明
     *  - `sourcePath`：源代码地址
     *  - `inputDir`：输入数据（in文件，out文件）地址
     *  - `outputDir`：输出数据（将文件输出放到这里）地址
     *
     */
    public Report handle(String sourcePath, String inputDir, String outputDir, RunData runData) {
        Report report = new Report();
        if (!DeleteFile.handle(new File(outputDir))) { // 清空输出目录
            return systemError();
        }
        if (!(new File(outputDir).mkdirs())) {
            return systemError();
        }

        if (compile != null) { // 如果必须得编译（对于Python等脚本文件可以不传入编译器）
            CompileState compileState = compile.handle(sourcePath);
            if (compileState != CompileState.SUCCESS) {
                report.setState(ReportState.decorate(compileState));
                return report;
            }
        }

        report = run.handle(sourcePath, inputDir, outputDir, runData); // 运行程序
        if (report.getState() != ReportState.AC) {
            return report;
        }

        return compare.handle(report, inputDir, outputDir); // 比较输出结果
    }

    private static Report systemError() {
        Report report = new Report();
        report.setState(ReportState.SE);
        return report;
    }
}
